home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
- #include <stdio.h>
- #ifndef NOUNISTD_H
- #include <unistd.h>
- #endif
- #include "head.h"
-
- #define ERRR (-1)
-
- static double gammq(double a, double x);
- static double betai(double a, double b, double x);
- static double betacf(double a, double b, double x);
- static void gser(double *gamser, double a, double x, double *gln);
- static void gcf(double *gammcf, double a, double x, double *gln);
- static double sqrarg;
- #define SQR(a) (sqrarg=(a),sqrarg*sqrarg)
-
- void Ft_fit(double *x, double *y, int ndata, double *sig, int mwt, double *a, double *b, double *siga, double *sigb, double *chi2, double *q)
- {
- int i;
- double wt,t,sxoss,sx=0.0,sy=0.0,st2=0.0,ss,sigdat;
-
- *b=0.0;
- if (mwt) {
- ss=0.0;
- for (i=1;i<=ndata;i++) {
- wt=1.0/SQR(sig[i]);
- ss += wt;
- sx += x[i]*wt;
- sy += y[i]*wt;
- }
- } else {
- for (i=1;i<=ndata;i++) {
- sx += x[i];
- sy += y[i];
- }
- ss=ndata;
- }
- sxoss=sx/ss;
- if (mwt) {
- for (i=1;i<=ndata;i++) {
- t=(x[i]-sxoss)/sig[i];
- st2 += t*t;
- *b += t*y[i]/sig[i];
- }
- } else {
- for (i=1;i<=ndata;i++) {
- t=x[i]-sxoss;
- st2 += t*t;
- *b += t*y[i];
- }
- }
- *b /= st2;
- *a=(sy-sx*(*b))/ss;
- *siga=sqrt((1.0+sx*sx/(ss*st2))/ss);
- *sigb=sqrt(1.0/st2);
- *chi2=0.0;
- if (mwt == 0) {
- for (i=1;i<=ndata;i++)
- *chi2 += SQR(y[i]-(*a)-(*b)*x[i]);
- *q=1.0;
- sigdat=sqrt((*chi2)/(ndata-2));
- *siga *= sigdat;
- *sigb *= sigdat;
- } else {
- for (i=1;i<=ndata;i++)
- *chi2 += SQR((y[i]-(*a)-(*b)*x[i])/sig[i]);
- *q=gammq(0.5*(ndata-2),0.5*(*chi2));
- }
- }
-
- #undef SQR
-
- static double gammq(double a, double x)
- {
- double gamser,gammcf,gln;
-
- if (x < 0.0 || a <= 0.0) {
- fputs("gammq: Invalid arguments in routine.\n", stderr);
- return(ERRR);
- }
- if (x < (a+1.0)) {
- gser(&gamser,a,x,&gln);
- return 1.0-gamser;
- } else {
- gcf(&gammcf,a,x,&gln);
- return gammcf;
- }
- }
-
- #define ITMAX 100
- #define EPS 3.0e-7
-
- static void gser(double *gamser, double a, double x, double *gln)
- {
- int n;
- double sum,del,ap;
-
- *gln=lgamma(a);
- if (x <= 0.0) {
- if (x < 0.0) {
- fputs("gser: x less < 0.\n", stderr);
- return;
- }
- *gamser=0.0;
- return;
- } else {
- ap=a;
- del=sum=1.0/a;
- for (n=1;n<=ITMAX;n++) {
- ap += 1.0;
- del *= x/ap;
- sum += del;
- if (fabs(del) < fabs(sum)*EPS) {
- *gamser=sum*exp(-x+a*log(x)-(*gln));
- return;
- }
- }
- fputs("gser: variable a too large; ITMAX too small.\n", stderr);
- return;
- }
- }
-
- static void gcf(double *gammcf, double a, double x, double *gln)
- {
- int n;
- double gold=0.0,g,fac=1.0,b1=1.0;
- double b0=0.0,anf,ana,an,a1,a0=1.0;
-
- *gln=lgamma(a);
- a1=x;
- for (n=1;n<=ITMAX;n++) {
- an=(double) n;
- ana=an-a;
- a0=(a1+a0*ana)*fac;
- b0=(b1+b0*ana)*fac;
- anf=an*fac;
- a1=x*a0+anf*a1;
- b1=x*b0+anf*b1;
- if (a1) {
- fac=1.0/a1;
- g=b1*fac;
- if (fabs((g-gold)/g) < EPS) {
- *gammcf=exp(-x+a*log(x)-(*gln))*g;
- return;
- }
- gold=g;
- }
- }
- fputs("gcf: variable a too large; ITMAX too small.\n", stderr);
- }
-
- #undef ITMAX
- #undef EPS
-
- #define TINY 1.0e-20
-
- void Ft_pearsn(double *x, double *y, int n, double *r, double *prob, double *z)
- {
- int j;
- double yt,xt,t,df;
- double syy=0.0,sxy=0.0,sxx=0.0,ay=0.0,ax=0.0;
-
- for (j=1;j<=n;j++) {
- ax += x[j];
- ay += y[j];
- }
- ax /= n;
- ay /= n;
- for (j=1;j<=n;j++) {
- xt=x[j]-ax;
- yt=y[j]-ay;
- sxx += xt*xt;
- syy += yt*yt;
- sxy += xt*yt;
- }
- *r=sxy/sqrt(sxx*syy);
- *z=0.5*log((1.0+(*r)+TINY)/(1.0-(*r)+TINY));
- df=n-2;
- t=(*r)*sqrt(df/((1.0-(*r)+TINY)*(1.0+(*r)+TINY)));
- *prob=betai(0.5*df,0.5,df/(df+t*t));
- }
-
- #define ITMAX 100
- #define EPS 3.0e-7
-
- static double betacf(double a, double b, double x)
- {
- double qap,qam,qab,em,tem,d;
- double bz,bm=1.0,bp,bpp;
- double az=1.0,am=1.0,ap,app,aold;
- int m;
-
- qab=a+b;
- qap=a+1.0;
- qam=a-1.0;
- bz=1.0-qab*x/qap;
- for (m=1;m<=ITMAX;m++) {
- em=(double) m;
- tem=em+em;
- d=em*(b-em)*x/((qam+tem)*(a+tem));
- ap=az+d*am;
- bp=bz+d*bm;
- d = -(a+em)*(qab+em)*x/((qap+tem)*(a+tem));
- app=ap+d*az;
- bpp=bp+d*bz;
- aold=az;
- am=ap/bpp;
- bm=bp/bpp;
- az=app/bpp;
- bz=1.0;
- if (fabs(az-aold) < (EPS*fabs(az)))
- return(az);
- }
- fputs("BETACF: a or b too big, or ITMAX too small.\n", stderr);
- Ft_catcher(ERRR);
- return(ERRR);
- }
-
- #undef ITMAX
- #undef EPS
-
- static double betai(double a, double b, double x)
- {
- double bt;
-
- if (x < 0.0 || x > 1.0) {
- fputs("BETAI: Bad x.\n", stderr);
- Ft_catcher(ERRR);
- }
- if (x == 0.0 || x == 1.0) bt=0.0;
- else
- bt=exp(lgamma(a+b)-lgamma(a)-lgamma(b)+a*log(x)+b*log(1.0-x));
- if (x < (a+1.0)/(a+b+2.0))
- return(bt*betacf(a,b,x)/a);
- else
- return(1.0-bt*betacf(b,a,1.0-x)/b);
- }
-